﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.DataAnnotations;

namespace My.Common.EntityHelper
{
    public class EntityHelper : IEntityHelper
    {
        public int GetKeyValue<T>(T dto)
        {
            var keyPropertyInfo = GetKeyProperty(dto.GetType());
            if (keyPropertyInfo != null)
            {
                return (int)keyPropertyInfo.GetValue(dto, null);
            }
            else
            {
                throw new System.Exception("This object does not have key.");
            }
        }

        public void SetKeyValue<T>(T dto, int keyValue)
        {
            var keyName = GetKeyName(dto.GetType());
            SetValueOfProperty(dto, keyName, keyValue);
        }

        public bool IsNewDTO<T>(T dto)
        {
            return (GetKeyValue(dto) < 1);
        }

        public PropertyInfo GetKeyProperty(Type dtoType)
        {
            var properties = dtoType.GetProperties();
            foreach (var property in properties)
            {
                var custAttributes = property.GetCustomAttributes(true);
                var keyAtt = custAttributes.FirstOrDefault(x => x.GetType() == typeof(KeyAttribute));
                if (keyAtt != null)
                {
                    return property;
                }
            }

            return null;
        }

        public object GetValueOfProperty<T>(T entity, string propertyName)
        {
            var propertyInfo = entity.GetType().GetProperty(propertyName);
            return propertyInfo.GetValue(entity, null);
        }

        public string GetKeyName(Type entityType)
        {
            var propertyInfo = GetKeyProperty(entityType);
            return (propertyInfo != null ? propertyInfo.Name : string.Empty);
        }

        public void SetValueOfProperty<T>(T entity, string propertyName, object value)
        {
            var propertyInfo = entity.GetType().GetProperty(propertyName);
            propertyInfo.SetValue(entity, value, null);
        }

        public PropertyInfo GetProperty(Type entityType, string propertyName)
        {
            return entityType.GetProperty(propertyName);
        }
    }
}
